import type { BrowserWindow } from 'electron'
import { BrowserView, dialog, ipcMain } from 'electron'
import { useStore } from './store'

const browserViews: Map<number, BrowserView> = new Map()

export function initViews(win: BrowserWindow) {
  ipcMain.on('view-start-create',(_event, url) => {
    createView(win, url)
      .catch(console.error)
  })
  ipcMain.on('view-start-history-change', (_event, id, opt) => {
    const v = browserViews.get(id)
    if (v) {
      switch (opt) {
        case 'back':
          if (v.webContents.canGoBack()) {
            v.webContents.goBack()
          }
          break
        case 'forward':
          if (v.webContents.canGoForward()) {
            v.webContents.goForward()
          }
          break
        case 'refresh':
          v.webContents.reload()
          break
        default:
          console.log('no matching opt.')
      }
    }
  })
  ipcMain.on('view-remove', (_event, id, nextId) => {
    browserViews.delete(id)
    if (browserViews.size === 0) {
      win.setBrowserView(null)
    } else if (nextId) {
      const v = browserViews.get(nextId)
      win.setBrowserView(v || null)
    }
  })
  ipcMain.on('view-active', (_event, id) => {
    const v = browserViews.get(id)
    win.setBrowserView(v || null)
  })
}

// let index = 1

function createView(win: BrowserWindow, url: string) {
  const store = useStore()

  const view = new BrowserView()
  browserViews.set(view.webContents.id, view)
  win.setBrowserView(view)

  // 设置 BrowserView 的样式
  const rect = win.getContentBounds()
  view.setBounds({ x: 0, y: 113, width: rect.width, height: rect.height - 113 })
  view.setAutoResize({ width: true, height: true })
  view.setBackgroundColor('#ffffff')

  // 监听 BrowserView 内容相关的事件
  view.webContents.setWindowOpenHandler((details) => {
    const canOpen = store.getPages()
      .some(page => new RegExp(page.url).test(url)
        && page.ban_urls
        && (JSON.parse(page.ban_urls) as string[]).every(u => details.url.indexOf(u) < 0))
    if (canOpen) {
      createView(win, details.url)
        .catch(console.error)
    } else {
      dialog.showMessageBox({
        type: 'info',
        title: '提示',
        message: '此板块暂未开通!',
        buttons: ['关闭']
      }).catch(console.error)
    }
    return { action: 'deny' }
  })
  view.webContents.on('frame-created', (_event, details) => {
    if (!details.frame.parent) {
      win.webContents.send('view-main-frame-created', view.webContents.id)
    }
  })
  view.webContents.on('did-start-loading', () => {
    win.webContents.send('view-did-start-loading', view.webContents.id)
  })
  view.webContents.on('did-start-navigation', () => {
    initViewCSS(view)
    win.webContents.send('view-did-start-navigation', view.webContents.id, view.webContents.getURL())
  })
  view.webContents.on('did-stop-loading', () => {
    win.webContents.send('view-did-stop-loading', view.webContents.id, view.webContents.canGoBack(), view.webContents.canGoForward())
  })
  view.webContents.on('page-favicon-updated', (_event, favicons) => {
    win.webContents.send('view-page-favicon-updated', view.webContents.id, favicons)
  })
  view.webContents.on('page-title-updated', (_event, title) => {
    win.webContents.send('view-page-title-updated', view.webContents.id, title)
  })

  return view.webContents.loadURL(url)

  // 事件顺序
  // 1 frame-created
  // 2 did-start-loading
  // 3 did-start-navigation
  // 4 did-frame-navigate
  // 5 did-navigate
  // 7 did-start-navigation
  // 8 did-navigate-in-page
  // 9 dom-ready
  // 12 did-frame-finish-load
  // 13 did-finish-load
  // 14 did-stop-loading

  // frame-created
  // did-start-loading
  // did-start-navigation
  // did-frame-navigate
  // did-navigate
  // dom-ready
  // did-start-navigation
  // did-navigate-in-page
  // did-frame-finish-load
  // did-finish-load
  // did-stop-loading

  // 内部导航
  // did-start-loading
  // did-start-navigation
  // did-navigate-in-page
  // did-stop-loading
  // page-favicon-updated
  // page-title-updated

  // view.webContents.on('did-start-loading', () => {
  //   console.log(index++, 'did-start-loading')
  //   win.webContents.send('view-did-start-loading')
  // })
  // view.webContents.on('did-finish-load', () => {
  //   console.log(index++, 'did-finish-load')
  //   win.webContents.send('view-did-finish-load')
  // })
  // view.webContents.on('did-fail-load', () => {
  //   console.log(index++, 'did-fail-load')
  //   win.webContents.send('view-did-fail-load')
  // })
  // view.webContents.on('did-frame-finish-load', () => {
  //   console.log(index++, 'did-frame-finish-load')
  //   win.webContents.send('view-did-frame-finish-load')
  // })
  // view.webContents.on('did-stop-loading', () => {
  //   console.log(index++, 'did-stop-loading')
  //   win.webContents.send('view-did-stop-loading')
  // })
  // view.webContents.on('dom-ready', () => {
  //   console.log(index++, 'dom-ready')
  //   win.webContents.send('view-dom-ready')
  // })
  // view.webContents.on('page-title-updated', () => {
  //   console.log(index++, 'page-title-updated')
  //   win.webContents.send('view-page-title-updated')
  // })
  // view.webContents.on('page-favicon-updated', () => {
  //   console.log(index++, 'page-favicon-updated')
  //   win.webContents.send('view-page-favicon-updated')
  // })
  // view.webContents.on('content-bounds-updated', () => {
  //   console.log(index++, 'content-bounds-updated')
  //   win.webContents.send('view-content-bounds-updated')
  // })
  // view.webContents.on('did-create-window', (event) => {
  //   console.log('did-create-window:', event)
  //   win.webContents.send('view-did-create-window')
  // })
  // view.webContents.on('will-navigate', () => {
  //   console.log(index++, 'will-navigate')
  //   win.webContents.send('view-will-navigate')
  // })
  // view.webContents.on('will-frame-navigate', () => {
  //   console.log(index++, 'will-frame-navigate')
  //   win.webContents.send('view-will-frame-navigate')
  // })
  // view.webContents.on('did-start-navigation', () => {
  //   console.log(index++, 'did-start-navigation')
  //   win.webContents.send('view-did-start-navigation')
  // })
  // view.webContents.on('will-redirect', () => {
  //   console.log(index++, 'will-redirect')
  //   win.webContents.send('view-will-redirect')
  // })
  // view.webContents.on('did-redirect-navigation', () => {
  //   console.log(index++, 'did-redirect-navigation')
  //   win.webContents.send('view-did-redirect-navigation')
  // })
  // view.webContents.on('did-navigate', () => {
  //   console.log(index++, 'did-navigate')
  //   win.webContents.send('view-did-navigate')
  // })
  // view.webContents.on('did-frame-navigate', () => {
  //   console.log(index++, 'did-frame-navigate')
  //   win.webContents.send('view-did-frame-navigate')
  // })
  // view.webContents.on('did-navigate-in-page', () => {
  //   console.log(index++, 'did-navigate-in-page')
  //   win.webContents.send('view-did-navigate-in-page')
  // })
  // view.webContents.on('will-prevent-unload', () => {
  //   console.log(index++, 'will-prevent-unload')
  //   win.webContents.send('view-will-prevent-unload')
  // })
  // view.webContents.on('frame-created', () => {
  //   console.log(index++, 'frame-created')
  //   win.webContents.send('view-frame-created')
  // })
}

function initViewCSS(view: BrowserView) {
  const store = useStore()
  if (!store.isAdminRole()) {
    store.getPages().forEach(page => {
      const reg = new RegExp(page.url)
      if (reg.test(view.webContents.getURL())) {
        view.webContents.insertCSS(page.css)
          .catch(console.error)
      }
    })
  }
}
